/**
 * 
 */
package com.gragra.sampling.binary;
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
import com.gragra.sampling.PopulationProbabilityAssigner;
import com.gragra.sampling.PopulationSamplingStructure;
/**
 * @author Christoph Teichmann
 * 21.09.2013
 */
public class ConstSpanConverter implements ConvertSample
{
	/**
	 * 
	 */
	private String best = null;
	/**
	 * 
	 */
	private Object2IntOpenHashMap<String> observed = null;
	/* (non-Javadoc)
	 * @see com.gragra.sampling.binary.ConvertSample#getBest(com.gragra.sampling.binary.BinaryStructure, com.gragra.sampling.PopulationProbabilityAssigner)
	 */
	@Override
	public String getBest(PopulationSamplingStructure str,
			PopulationProbabilityAssigner pa)
	{return best;}
	/* (non-Javadoc)
	 * @see com.gragra.sampling.binary.ConvertSample#minRisk(com.gragra.sampling.binary.BinaryStructure, com.gragra.sampling.PopulationProbabilityAssigner)
	 */
	@Override
	public String minRisk(PopulationSamplingStructure str,
			PopulationProbabilityAssigner pa)
	{
		String choice = null;
		int best = Integer.MIN_VALUE;
		for(String s : this.observed.keySet())
		{
			int val = this.observed.getInt(s);
			if(val > best)
			{
				choice = s;
				best = val;
			}
		}
		return choice;
	}
	/* (non-Javadoc)
	 * @see com.gragra.sampling.binary.ConvertSample#addSample(com.gragra.sampling.binary.BinaryStructure)
	 */
	@Override
	public void addSample(PopulationSamplingStructure str)
	{
		if(this.observed == null)
		{this.observed = new Object2IntOpenHashMap<String>();}
		BinaryStructure bs = (BinaryStructure) str;
		ThreadedToString tts = (ThreadedToString) str;
		for(int thread=0;thread<tts.getNumberOfThreads();++thread)
		{
			String s = getConsts(bs,thread);
			this.observed.addTo(s, 1);
		}
	}
	/**
	 * 
	 * @param bs
	 * @param thread
	 * @return
	 */
	private String getConsts(BinaryStructure bs, int thread)
	{
		int node = bs.getRootPosition();
		return getConsts(node,bs,thread);
	}
	/**
	 * 
	 * @param node
	 * @param bs
	 * @param thread
	 * @return
	 */
	private String getConsts(int node, BinaryStructure bs, int thread)
	{
		StringBuilder sb = new StringBuilder();
		sb.append(Integer.toString(bs.getFrom(node, thread)));
		sb.append(";");
		sb.append(Integer.toString(bs.getTo(node, thread)));
		int n = bs.getDominated(node, true, thread);
		if(n >= bs.getLength())
		{
			sb.append(" ");
			sb.append(this.getConsts(n, bs, thread));
		}
		n = bs.getDominated(node, false, thread);
		if(n >= bs.getLength())
		{
			sb.append(" ");
			sb.append(this.getConsts(n, bs, thread));
		}
		return sb.toString();
	}
	/* (non-Javadoc)
	 * @see com.gragra.sampling.binary.ConvertSample#setBest(com.gragra.sampling.binary.BinaryStructure, int)
	 */
	@Override
	public void setBest(PopulationSamplingStructure str, int thread)
	{best = ((ThreadedToString) str).toString(thread);}
	@Override
	public double getNumberSeen(String goldTwo)
	{return this.observed.getInt(goldTwo.trim());}
}